package model;

import java.util.ArrayList;

import controller.Calculator;

/**
 * @author Alexander Müller
 * 
 */
public class Subnet {

	private int subnetSize, suffix, hostSpace;
	private IPAddress netAddress, mask, broadcastAddress;
	private ArrayList<IPAddress> ipAddressList = new ArrayList<IPAddress>();
	private String name;
	private final Calculator calc = Calculator.getInstance();


	public Subnet(IPAddress netAddress, int hosts, String name) {

		this.netAddress = netAddress;
		suffix = calc.calculateSuffixByHostNumber(hosts + 1);
		subnetSize = calc.calculateSubnetSize(suffix, netAddress);
		hostSpace = subnetSize;
		broadcastAddress = calc.calculateBroadcast(this.netAddress, hostSpace);
		mask = calc.calculateSubnetmask(suffix);
		this.name = validateName(name);

		addAdresses(hostSpace);
		initializeAddresses();
	}


	private void initializeAddresses() {
		this.netAddress.setAdditionalInfo(Constants.NETADDRESS);
		broadcastAddress.setAdditionalInfo(Constants.BROADCASTADDRESS);

	}

	public int getSuffix() {
		return suffix;
	}

	public void setSuffix(int suffix) {
		this.suffix = suffix;
	}

	public IPAddress getNetAdress() {
		return netAddress;
	}

	public void setNetAddress(IPAddress netAddress) {
		this.netAddress = netAddress;
	}

	public IPAddress getMask() {
		return mask;
	}

	public void setMask(IPAddress mask) {
		this.mask = mask;
	}


	public void setIpAddressList(ArrayList<IPAddress> ipAddressList) {
		this.ipAddressList = ipAddressList;
	}

	public ArrayList<IPAddress> getIpAddressList() {
		return ipAddressList;
	}
	
	public ArrayList<IPAddress> getFreeIPList(){
		ArrayList<IPAddress> freeIPList = new ArrayList<IPAddress>();
		for (IPAddress ip : ipAddressList){
			if (ip.getAdditionalInfo().equalsIgnoreCase("<Free>")){
				freeIPList.add(ip);
			}
		}
		return freeIPList;
	}
	
	public ArrayList<IPAddress> getAssignedIPList(){
		ArrayList<IPAddress> assignedIPList = new ArrayList<IPAddress>();
		for (IPAddress ip : ipAddressList){
			if (!ip.getAdditionalInfo().equalsIgnoreCase("<Free>")){
				assignedIPList.add(ip);
			}
		}
		return assignedIPList;
	}

	public boolean editIpAddress(IPAddress ipAddress, String additionalInfo) {
		
		for (IPAddress element : ipAddressList) {	
		
			if (element.getAddress().equals(ipAddress.getAddress())) {
			element.setAdditionalInfo(additionalInfo);
				return true;
			}
		}
		return false;

	}

	public boolean editIpAddress(String ip, String additionalInfo) {

		for (IPAddress element : ipAddressList) {

			if (element.getAddress().equals(ip)) {
				element.setAdditionalInfo(additionalInfo);
				return true;
			}
		}
		return false;

	}

	public double getSubnetSize() {
		return subnetSize;
	}

	public void setSubnetSize(int subnetSize) {
		this.subnetSize = subnetSize;
	}

	public IPAddress getBroadcastAddress() {
		return broadcastAddress;
	}

	public void setBroadcastAddress(IPAddress broadcastAddress) {
		this.broadcastAddress = broadcastAddress;
	}

	public int getHostSpace() {
		return hostSpace;
	}

	public void setHostSpace(int hostSpace) {
		this.hostSpace = hostSpace;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}





	private String validateName(String name) {

		if (name == null||name.equals(Constants.EMPTY)  ) {

			return netAddress.getAddress();
		} else {
			return name;
		}
	}

	private void addAdresses(int hosts) {

		int firstBit, secondBit, thirdBit, fourthBit;
			firstBit = netAddress.getAddressBits(0).getBitValue();
			secondBit = netAddress.getAddressBits(1).getBitValue();
			thirdBit = netAddress.getAddressBits(2).getBitValue();
			fourthBit = netAddress.getAddressBits(3).getBitValue();


		for (int range = 0; range < hosts; range++) {

			fourthBit++;

			if (fourthBit > 255) {
				fourthBit = 0;
				thirdBit++;
			}
			if (thirdBit > 255) {
				thirdBit = 0;
				secondBit++;
			}
			if (secondBit > 255) {
				secondBit = 0;
				firstBit++;
			}

			IPAddress ip = new IPAddress(Integer.toString(firstBit)
					+ Constants.POINT + Integer.toString(secondBit)
					+ Constants.POINT + Integer.toString(thirdBit)
					+ Constants.POINT + Integer.toString(fourthBit));

			ip.setAdditionalInfo(Constants.FREEIP);

			ipAddressList.add(ip);
		}

	}


}
